<template>
	<view class="load-refresh">
		<!-- 数据列表块 -->
		<view class="cover-container">
			<scroll-view
				class="list"
				:refresher-enabled="isRefresh"
				refresher-threshold="45"
				refresher-default-style="none"
				:refresher-triggered="isRefresh && refresherTriggered"
				@refresherrefresh="refresherrefresh"
				@refresherpulling="refresherpulling"
				@refresherrestore="refresherrestore"
				scroll-y
				:bounces="true"
				:enable-back-to-top="true"
				:scroll-top="scrollTop"
				:style="{height: getHeight, backgroundColor: backgroundCover}"
				@scrolltolower="loadMore"
				@scroll="handlerOnScroll"
			>
				<!-- 刷新动画，可自定义，占高100rpx -->
				<view class="refresh-container animation" v-show="showRefreshLoading" :style="{top: animationTop + 'px'}">
					<!-- <view v-if="!playState" class="remind">
						{{moving ? '↑ 松开释放' : '↓ 下拉刷新'}}
					</view> -->
					<view v-if="playState && refreshType === 'hollowDots'" class="refresh hollow-dots-spinner">
						<view class="dot"></view>
						<view class="dot"></view>
						<view class="dot"></view>
					</view>
					<view v-if="playState && refreshType === 'halfCircle'" class="refresh half-circle-spinner">
						<view class="circle circle-1"></view>
						<view class="circle circle-2"></view>
					</view>
					<view v-if="playState && refreshType === 'swappingSquares'" class="refresh swapping-squares-spinner">
						<view class="square"></view>
						<view class="square"></view>
						<view class="square"></view>
						<view class="square"></view>
					</view>
					<view v-if="refreshType === 'carCircle'" class="refresh car-circle-spinner">
						<image class="car" :class="{animation: playState}" src="../../static/images/loading.svg" />
					</view>
				</view>
				<!-- 数据集插槽 -->
				<slot name="content-list"></slot>
				<!-- 上拉加载 -->
				<view class="load-more" v-show="showLoadMore && currentPage===totalPages && !isLoadMore && updateType ==='more'">没有更多数据了</view>
				<view class="animation" v-show="isLoadMore && updateType==='more'">
					<view class="refresh car-circle-spinner">
						<image class="car animation" src="../../static/images/loading.svg" />
					</view>
				</view>
			</scroll-view>
		</view>
	</view>
</template>

<script>
	export default {
		name: 'loadRefresh',
		props: {
			isRefresh: {
				type: Boolean,
				default: true
			},
			showLoadMore: {
				type: Boolean,
				default: true
			},
			refreshType: {
				type: String,
				default: 'hollowDots'
			},
			fixedHeight: {
				type: String,
				default: '0'
			},
			heightReduce: {
				type: String,
				default: '0'
			},
			color: {
				type: String,
				default: '#04C4C4'
			},
			backgroundCover: {
				type: String,
				default: 'white'
			},
			currentPage: {
				type: Number,
				default: 0
			},
			totalPages: {
				type: Number,
				default: 0
			},
		},
		data() {
			const top = uni.upx2px(-100);
			return {
				initMarginTop: -0,
				isLoadMore: false,
				updating: false, // 数据更新状态（true: 更新中）
				updateType: 'refresh', // 数据更新类型（refres: 下拉刷新: more: 加载更多）
				playState: false, // 动画的状态 暂停 paused/开始 running
				scrollTop: -1,
				//
				showRefreshLoading: false,
				initAnimationTop: top,
				animationTop: top,
				refresherTriggered: false,
				gap: 0,
			}
		},
		computed: {
			// 计算组件所占屏幕高度
			getHeight() {
				// rpx = px / uni.getSystemInfoSync().windowWidth * 750
				if (Number(this.fixedHeight) > 0) {
					// console.log('fixedHeight height', this.fixedHeight);
					return this.fixedHeight + 'px';
				} else {
					let height = uni.getSystemInfoSync().windowHeight - uni.upx2px(0 + this.heightReduce)
					// console.log('heightReduce height', height);
					return height + 'px';
				}
			},
		},
		methods: {
			scrollToTop() {
				this.scrollTop = this.currentScrollTop + 10;
				this.$nextTick(() => {
					this.scrollTop = 0;
				});
			},
			// 根据currentPage和totalPages的值来判断 是否触发@loadMore
			loadMore() {
				const { updating, showLoadMore, currentPage, totalPages } = this;
				// console.log('loadMore', showLoadMore, currentPage, totalPages);
				if (!updating && showLoadMore && currentPage < totalPages) {
					this.updating = true;
					this.updateType = 'more';
					this.isLoadMore = true;
					this.$nextTick(() => {
						this.scrollTop = this.currentScrollTop - 1;
						this.scrollTop = this.currentScrollTop + uni.upx2px(100);
					});
					this.$emit('loadMore');
				}
			},
			runRefresh() {
				this.refresherrefresh();
			},
			completed() {
				if (this.comTime) clearTimeout(this.comTime);
				this.comTime = setTimeout(() => {
					this.isLoadMore = false;
					if (this.updateType === 'refresh') {
						// 下拉刷新
						this.animationTop = this.initAnimationTop;
						//
						this.showRefreshLoading = false;
						this.playState = false;
						this.refresherTriggered = false;
					}
					this.updating = false;
				}, 500);
			},
			handlerOnScroll(e) {
				this.currentScrollTop = e.detail.scrollTop;
				this.$emit('onScroll', e);
			},
			refresherpulling(e) {
				const dy = e.detail.dy;
				// console.log('refresh pulling', e, e.detail.dy);
				let gap = dy - 24;
				this.showRefreshLoading = dy >= 0;
				if (this.showRefreshLoading) {
					gap = gap - gap * 0.95;
				}
				this.animationTop = this.initAnimationTop + gap;
			},
			refresherrestore(e) {
				// console.log('refresh stop', e);
			},
			refresherrefresh(event) {
				this.showRefreshLoading = true;
				this.animationTop = uni.upx2px(-100);
				this.updating = true;
				this.playState = true;
				this.updateType = 'refresh';
				this.$nextTick(() => {
					this.refresherTriggered = true;
				});
				if (event) this.$emit('refresh');
			}
		}
	}
</script>

<style lang="scss" scoped>
	$color: var(--color);

	.load-refresh{
		margin: 0;
		padding: 0;
		width: 100%;
		position: relative;
		.cover-container {
			position: absolute;
			width: 100%;
			// margin-top: -100rpx;
			background-color: #fff;
			.list {
				position: relative;
				width: 100%;
				.load-more {
					font-size: 20rpx;
					text-align: center;
					color: #AAAAAA;
					padding: 16rpx;
					margin-bottom: 84rpx;
				}
			}
		}
	}

	/* 动画 */
	.refresh-container {
    position: absolute;
		top: -100rpx;
	}
	.animation {
		width: 100%;
		height: 100rpx;
		z-index: 999;
		.remind {
			width: 100%;
			height: 100rpx;
			text-align: center;
			line-height: 100rpx;
		}
		.refresh {
			width: 100%;
			height: 100rpx;
			display: flex;
			align-items: center;
			justify-content: center;
			box-sizing: border-box;
		}

		/* HollowDots  */
		.hollow-dots-spinner .dot {
		  width: 30rpx;
		  height: 30rpx;
		  margin: 0 calc(30rpx / 2);
		  border: calc(30rpx / 5) solid $color;
		  border-radius: 50%;
		  float: left;
		  transform: scale(0);
		  animation: hollowDots 1000ms ease infinite 0ms;
		}
		.hollow-dots-spinner .dot:nth-child(1) {
		  animation-delay: calc(300ms * 1);
		}
		.hollow-dots-spinner .dot:nth-child(2) {
		  animation-delay: calc(300ms * 2);
		}
		.hollow-dots-spinner .dot:nth-child(3) {
		  animation-delay: calc(300ms * 3);
		}
		@keyframes hollowDots {
		  50% {
			transform: scale(1);
			opacity: 1;
		  }
		  100% {
			opacity: 0;
		  }
		}

		/* halfCircle  */
		.half-circle-spinner .circle {
		  content: "";
		  position: absolute;
		  width: 60rpx;
		  height: 60rpx;
		  border-radius: 100%;
		  border: calc(60rpx / 10) solid transparent;
		}

		.half-circle-spinner .circle.circle-1 {
		  border-top-color: $color;
		  animation: halfCircle 1s infinite;
		}
		.half-circle-spinner .circle.circle-2 {
		  border-bottom-color: $color;
		  animation: halfCircle 1s infinite alternate;
		}
		.car-circle-spinner .car {
			width: 40rpx;
			height: 40rpx;
			&.animation {
				animation: halfCircle 1s infinite alternate;
			}
		}
		@keyframes halfCircle {
		  0% {
			transform: rotate(0deg);
		  }
		  100%{
			transform: rotate(360deg);
		  }
		}

		/* swappingSquares */
		.swapping-squares-spinner {
		  position: relative;
		}
		.swapping-squares-spinner .square {
		  height: calc(65rpx * 0.25 / 1.3);
		  width:  calc(65rpx * 0.25 / 1.3);
		  animation-duration: 1000ms;
		  border: calc(65rpx * 0.04 / 1.3) solid $color;
		  margin-right: auto;
		  margin-left: auto;
		  position: absolute;
		  animation-iteration-count: infinite;
		}
		.swapping-squares-spinner .square:nth-child(1) {
		  animation-name: swappingSquares-child-1;
		  animation-delay: 500ms;
		}
		.swapping-squares-spinner .square:nth-child(2) {
		  animation-name: swappingSquares-child-2;
		  animation-delay: 0ms;
		}
		.swapping-squares-spinner .square:nth-child(3) {
		  animation-name: swappingSquares-child-3;
		  animation-delay: 500ms;
		}
		.swapping-squares-spinner .square:nth-child(4) {
		  animation-name: swappingSquares-child-4;
		  animation-delay: 0ms;
		}
		@keyframes swappingSquares-child-1 {
		  50% {
			transform: translate(150%,150%) scale(2,2);
		  }
		}
		@keyframes swappingSquares-child-2 {
		  50% {
			transform: translate(-150%,150%) scale(2,2);
		  }
		}
		@keyframes swappingSquares-child-3 {
		  50% {
			transform: translate(-150%,-150%) scale(2,2);
		  }
		}
		@keyframes swappingSquares-child-4 {
		  50% {
			transform: translate(150%,-150%) scale(2,2);
		  }
		}
	}
</style>
